﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Jabr.Logic.Roster
{
    sealed public class DisplayableContact : DisplayableItem
    {
        private GenericPresence m_pres;
        private DisplayableGroup m_grp;
        private bool m_final;
        private string m_status;
        private string m_name;
        private AbstractAccount m_acc;

        public DisplayableContact()
        {
            this.m_pres = GenericPresence.OFFLINE;
            this.m_final = false;
            this.PresenceChanged += new PresenceDelegate(DisplayableContact_PresenceChanged);
        }
        public DisplayableContact(string id, string name)
        {
            this.m_pres = GenericPresence.OFFLINE;
            this.m_final = false;
            this.ContactID = id;
            this.ContactName = name;
            this.PresenceChanged += new PresenceDelegate(DisplayableContact_PresenceChanged);
        }
        private void DisplayableContact_PresenceChanged(GenericPresence presence, string status)
        {
            this.Text = this.ContactName + " // " + presence.ToString();
        }

        public bool IsInitialized
        {
            get
            {
                return this.m_final;
            }
            set
            {
                if (this.m_final)
                    throw new InvalidOperationException();
                this.m_final = value;
            }
        }

        public string ContactID
        {
            get
            {
                return this.Name;
            }
            set
            {
                this.Name = value;
            }
        }
        public string ContactName
        {
            get
            {
                return this.m_name;
            }
            set
            {
                if (this.IsInitialized)
                    if (this.m_grp != null)
                        this.Account.ContactUpdate(this.ContactID, value, this.m_grp.GroupName);
                    else
                        this.Account.ContactUpdate(this.ContactID, value, null);
                if (string.IsNullOrEmpty(value))
                    this.Text = this.ContactID;
                else
                    this.Text = value;
                this.m_name = value;
                this.DisplayableContact_PresenceChanged(this.PresenceValue, this.PresenceStatus);
            }
        }

        public GenericPresence PresenceValue
        {
            get
            {
                return this.m_pres;
            }
            set
            {
                this.m_pres = value;
                if (this.PresenceChanged != null)
                    this.PresenceChanged(this.m_pres, this.m_status);
            }
        }
        public string PresenceStatus
        {
            get
            {
                return this.m_status;
            }
            set
            {
                this.m_status = value;
            }
        }
        public delegate void PresenceDelegate(GenericPresence presence, string status);
        public event PresenceDelegate PresenceChanged;

        public AbstractAccount Account
        {
            get
            {
                return this.m_acc;
            }
            set
            {
                this.m_acc = value;
            }
        }

        public void Add()
        {
            if (this.IsInitialized)
                if (this.m_grp != null)
                    this.Account.ContactAdd(this.ContactID, this.ContactName, this.m_grp.GroupName);
                else
                    this.Account.ContactAdd(this.ContactID, this.ContactName, null);
        }
        public void Delete()
        {
            if (this.IsInitialized)
                this.Account.ContactRemove(this.ContactID);
            this.Remove();
        }

        public void Subscribe()
        {
            this.Account.ContactSubscribe(this.ContactID);
        }
        public void Unsubscribe()
        {
            this.Account.ContactUnsubscribe(this.ContactID);
        }

        public void PresenceSend(GenericPresence pres, string status)
        {
            if (this.IsInitialized)
                this.Account.PresenceTo(this.ContactID, pres, status);
        }
        public void PresenceProbe()
        {
            if (this.IsInitialized)
                this.Account.PresenceFrom(this.ContactID);
        }

        public void GroupAdd(DisplayableGroup grp)
        {
            if (this.m_grp != null)
                this.m_grp.ContactRemove(this);
            grp.ContactAdd(this);
            this.m_grp = grp;
            if (this.IsInitialized)
                this.Account.ContactUpdate(this.ContactID, this.ContactName, this.m_grp.GroupName);
        }
        public void GroupRemove()
        {
            if (this.m_grp != null)
            {
                this.m_grp.ContactRemove(this);
                this.m_grp = null;
                if (this.IsInitialized)
                    this.Account.ContactUpdate(this.ContactID, this.ContactName, null);
            }
        }
    }
}
